<template>
	<view id="popover" class="ui-popover">
		<view
			:id="popoverBoxId"
			class="popover-box"
			@touchend="onTouchend"
			@touchstart="onTouchstart"
		>
			<slot></slot>
		</view>
		<!-- mode -->
		<view
			@click.stop="close(50)"
			:id="popoverContentId"
			class="popover-content"
			:style="data.showStyle"
		>
			<div class="menu">
				<slot name="bubble">
					<div @click="emits('clickMenu', 'copy')" class="item">
						<div>复制</div>
					</div>
					<div @click="emits('clickMenu', 'quote')" class="item">
						<div>引用</div>
					</div>
					<div @click="emits('clickMenu', 'withdraw')" class="item">
						<div>撤回</div>
					</div>
					<div @click="emits('clickMenu', 'delete')" class="item">
						<div>删除</div>
					</div>
				</slot>
				<!-- 小三角 -->
				<div :style="data.iconStyle" class="icon"></div>
			</div>
		</view>
		<view
			v-show="data.popoverShow"
			@touchstart="close"
			@click="close"
			class="popover-bg"
		></view>
	</view>
</template>

<script setup>
// 组件

// 工具包
import { router } from '@/config/router/index.js';
import { api } from '@/api/index.js';
import { utils } from '@/common/utils.js';

// uniapp & vue
import { onLoad, onReady } from '@dcloudio/uni-app';
import { reactive, ref, watch, computed, nextTick } from 'vue';

// pinia

const emits = defineEmits(['clickMenu']);

const systemInfo = uni.getSystemInfoSync();
const popoverBoxId = `ID${utils.uuid()}`;
const popoverContentId = `ID${utils.uuid()}`;
const data = reactive({
	popoverShow: false,
	defaultStyle: {},
	showStyle: {
		left: 0,
		right: '',
		transform: '',
	},
	iconStyle: {
		left: '',
		right: '',
		transform: '',
	},
});

/**
 * @name  获取DOM
 */
const getDom = dom => {
	return new Promise((resolve, reject) => {
		const query = uni.createSelectorQuery(this);
		let select = query.select(dom);
		const boundingClientRect = select.boundingClientRect(data => {
			resolve(data);
		});
		boundingClientRect.exec();
	});
};

// 弹起 长按5
let pressDownTime = 0;
let time = null;
const onTouchstart = () => {
	time && clearTimeout(time);
	time = setTimeout(open, 500);
};

const onTouchend = () => {
	time && clearTimeout(time);
};

const open = async () => {
	let popoverContent = await getDom(`#${popoverContentId}`);
	let popoverBox = await getDom(`#${popoverBoxId}`);

	// 缩放中心点
	let originX = popoverBox.width / 2;
	// 根据距离 初始化位置 判断是顶部还是底部
	let isTop = popoverBox.top - 50 > popoverContent.height;
	// 上面还是下面
	data.defaultStyle = {
		top: isTop ? '-20rpx' : 'auto',
		bottom: !isTop ? '-20rpx' : 'auto',
		transform: `translateY(${isTop ? '-100%' : '100%'}) scale(.8)`,
	};
	// 左边还是右边
	if (popoverBox.left > systemInfo.windowWidth - popoverBox.right) {
		data.defaultStyle.right = 0;
		// 动画缩放中心点
		data.defaultStyle['transform-origin'] = `${popoverContent.width - originX}px ${
			isTop ? '100%' : '0%'
		}`;
	} else {
		data.defaultStyle.left = 0;
		// 动画缩放中心点
		data.defaultStyle['transform-origin'] = `${originX}px ${isTop ? '100%' : '0%'}`;
	}
	data.showStyle = { ...data.defaultStyle };
	// icon位置样式
	let iconDefsultStyle = {
		transform: `translate(0%, ${isTop ? '20%' : '-20%'})`,
		'border-top-color': isTop ? '#696969' : '',
		'border-bottom-color': !isTop ? '#696969' : '',
		top: !isTop ? '-20rpx' : 'auto',
		bottom: isTop ? '-20rpx' : 'auto',
	};

	setTimeout(() => {
		if (popoverBox.left > systemInfo.windowWidth - popoverBox.right) {
			data.showStyle = {
				// 位置
				...data.defaultStyle,
				// 显示
				opacity: 1,
				transform: `translateY(${isTop ? '-100%' : '100%'}) scale(1)`,
				'pointer-events': 'auto',
			};
			data.iconStyle = {
				right: `${originX}px`,
				left: 'auto',
				...iconDefsultStyle,
			};
		} else {
			data.showStyle = {
				// 位置
				...data.defaultStyle,
				// 显示
				opacity: 1,
				transform: `translateY(${isTop ? '-100%' : '100%'}) scale(1)`,
				'pointer-events': 'auto',
			};
			data.iconStyle = {
				left: `${originX}px`,
				right: 'auto',
				...iconDefsultStyle,
			};
		}

		if (!data.popoverShow) data.popoverShow = true;
	}, 200);
};

const close = time => {
	setTimeout(() => {
		data.popoverShow = false;
		data.showStyle = data.defaultStyle;
	}, time || 0);
};
</script>

<style lang="scss" scoped>
.ui-popover {
	position: relative;
	.popover-box {
		width: fit-content;
	}
	.popover-content {
		width: fit-content;
		transition: all 0.2s;
		z-index: 5;
		position: absolute;
		top: 0;
		opacity: 0;
		pointer-events: none;
	}

	.popover-bg {
		width: 100%;
		height: 100%;
		position: fixed;
		left: 0;
		top: 0;
		z-index: 4;
	}

	.menu {
		width: 456rpx;
		height: 120rpx;
		display: flex;
		background-color: #696969;
		display: flex;
		color: #fff;
		border-radius: 15rpx;
		font-size: 26rpx;
		padding: 0 10rpx;
		box-sizing: border-box;
		position: relative;
		.icon {
			border: 15rpx solid transparent;
			position: absolute;
		}
		.item {
			flex: 1;
			height: 120rpx;
			text-align: center;
			display: flex;
			flex-direction: column;
			justify-content: center;
			align-items: center;
		}
		image {
			width: 26rpx;
			height: 26rpx;
			margin-bottom: 8rpx;
		}
	}
}
</style>
